// Obtain shared preferences.
import 'dart:convert';
import 'dart:ffi';
import 'dart:math';

import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:xim/business/model/secret.dart';
import 'package:xim/config/config.dart';
import 'package:xim/http/apis/secret/secret_model.dart';
import 'apis.dart';
import 'ase.dart';

String _privateKey  = "privateKey";
String _publicKey  = "publicKey";
String _token  = "token";
String _account  = "account";
// Create storage
const storage = FlutterSecureStorage();

final Future<SharedPreferences> prefs =  SharedPreferences.getInstance();

enum StoreKey {
  privateKey(key: "privateKey"),
  publicKey(key: "publicKey"),
  token(key: "token"),
  account(key: "account"),
  isEnableFingerprintLogin(key: "isEnableFingerprintLogin"),
  isEnableFaceLogin(key: "isEnableFaceLogin"),
  isEnableGestureLogin(key: "isEnableGestureLogin"),
  localIdentityVerifyType(key: "localIdentityVerifyType"),
  sessionSecretKey(key: "sessionSecretKey"),
  ;
  final String key;
  const StoreKey({required this.key});
}

/// 存储
void storeString(StoreKey key, String value){
  prefs.then((it)=>it.setString(key.key, value));
}

void storeBool(StoreKey key, bool value){
  prefs.then((it)=>it.setBool(key.key, value));
}

Future<void> storeInt(StoreKey key, int value) async {
  return await prefs.then((it)=>it.setInt(key.key, value));
}
Future<int?> takeInt(StoreKey key) async {
  return await prefs.then((it)=>it.getInt(key.key));
}
/// 获取
Future<String?> takeAsString(StoreKey key) async {
  return await prefs.then((value) => value.getString(key.key));
}

Future<bool?> takeAsBool(StoreKey key) async {
  return await prefs.then((value) => value.getBool(key.key));
}

Future<int?> takeAsInt(StoreKey key) async {
  return await prefs.then((value) => value.getInt(key.key));
}

/// 本地身份校验方式
Future<void> storeLocalIdentityVerifyType(LocalIdentityVerifyType type) async {
  return await storeInt(StoreKey.localIdentityVerifyType, type.code);
}

Future<LocalIdentityVerifyType> takeLocalIdentityVerifyType() async {
  int? code =  await takeInt(StoreKey.localIdentityVerifyType);
  return Future(() => LocalIdentityVerifyType.parse(code));
}

// /// 安全
Future<void> secureStore(StoreKey key, String value) async {
  return await storage.write(key: key.key, value: value);
}

Future<String?> secureTake(StoreKey key) async {
  return await storage.read(key: key.key);
}

Future<void> secureStoreSessionSecretKey(SessionSecretKeyModel model){
  return storage.write(
      key:StoreKey.sessionSecretKey.key + model.sessionId.toString(),
      value: json.encode(model.toJson())
  );
}

Future<SessionSecretKeyModel?> secureTakeSessionSecretKey(int sessionId) async {
  var model = await storage.read(key:StoreKey.sessionSecretKey.key + sessionId.toString() );
  if(model==null){
    return null;
  }
  return SessionSecretKeyModel.fromJson(json.decode(model));
}

void storeUserAccount(String account){
  prefs.then((value) {
    value.setString(_account, account);
  });
}

@deprecated
Future<String?> getUserAccount() async {

  return await prefs.then((value) => value.getString(_account));
}

Future<String?> getUserToken() async {
  return await prefs.then((value) => value.getString(_token));
}


void storePublicKey(String publicKey, {String? salt}){
  prefs.then((value) {
    value.setString(_publicKey, publicKey);
  });
}

Future<String?> getPublicKey(String publicKey, {String? salt}) async {
  var pf = await prefs;
  return pf.getString(_publicKey);
}

void clearPublicKey() async {
  var pf = await prefs;
  await pf.remove(_publicKey);
}

void clearPrivateKey() async {
  var pf = await prefs;
  await pf.remove(_privateKey);
}

Future<String?> getPrivateKey({String? salt}) async {
  var privateKey = await prefs.then((value) => value.getString(_privateKey));
  if (privateKey == null){
    return null;
  }
  if( salt != null ){
    return AES.decryptAes(encryptedBase64Text: privateKey, aseKey: salt);
  }
  return privateKey;
}


String getRandomString(int length) {
  Random random = Random();
  List<String> digits =
  List.generate(length, (_) => random.nextInt(10).toString());
  return digits.join();
}
